#include <iostream>
#include <sstream>
#include <vector>

struct AminoAcid {
  bool h; ///< false if hydrophobic (non-polar), true if hydrophillic (polar)
  int x; ///< X coordinate of the amino acid.
  int y; ///< Y coordinate of the amino acid.

  /**
   * Default constructor
   */
  AminoAcid(bool argH = false, int argX = 0, int argY = 0) {
    h = argH;
    x = argX;
    y = argY;
  } // AminoAcid constructor

  /// Copy constructor
  AminoAcid(const AminoAcid& arg) {
    h = arg.h;
    x = arg.x;
    y = arg.y;
  }

  /**
   * Convenience method to print the information about the AminoAcid object itself.
   * @return std::string A string object.
   */
  std::string toString() {
    std::ostringstream ret;
    ret << (h ? "H " : "P ");
    ret << x << " " << y;

    return ret.str();
  } // toString() method

}; // AminoAcid class

/**
 * One of the most important classes in the PROFO project - Protein class.
 * It is also a major building block of the MVC pattern the whole project is built
 * upon. An object of this type is a Model for our view(ers) and controller(s).
 *
 * Initially a Protein object does not contain any amino acid. We can either
 * populate it by using parseInput() method, or by adding individual amino 
 * acids one-by-one using append() method.
 */
class Protein {
  public:
  // We will let compiler generate default constructor and constructor for us.

  /**
   * A method to parse give input string and generate a protein chain.
   *
   * TODO: Add check for exception, becuase it is possible that we run out of
   * memory.
   *
   * Complexity: O(n) where n is equal to arg.length() (size of the input string).
   */
  void parseInput(const std::string& arg) {
    AminoAcid tmp;
    int idx = 0;
    for (int i = 0; i<arg.length(); i++) {
      if ((arg[i] == '1') || (arg[i] == 'H')) {
        tmp.h = true;
        tmp.x = idx+2; // We make some space between first amino acid and the X
                       // coordinate.
        tmp.y = 2;     // by default, initial Y coordinate is 2
        _chain.push_back(tmp);
        ++idx;
      }
      if ((arg[i] == '0') || (arg[i] == 'P')) {
        tmp.h = false;
        tmp.x = idx+2; // same here, we start from 2
        tmp.y = 2;
        _chain.push_back(tmp);
        ++idx;
      }
    } // for
  } // parseInput() method

  /**
   * A version of parseInput() which takes a C-string as an argument.
   */
  void parseInput(const char* arg) {
    std::string str(arg);
    parseInput(str);
  } // parseInput() method

  // ACCESSOR methods ---------------------------------------------------------

  /**
   * A method to get the amino acid with the index arg.
   * Since no exception checks have been performed we will return the last
   * protein in the chain if given argument is out of bounds.
   *
   * @returns AminoAcid An AminoAcid object 
   */
  AminoAcid get(int arg) {
    if (arg > _chain.size()-1) {
      return _chain.back();
    } else {
      return _chain[arg];
    }
  } // get() method

  /**
   * Appends given amino acid ti the protein chain.
   */
  void append(const AminoAcid& arg) {
    _chain.push_back(arg);
  }

  private:
  std::vector<AminoAcid> _chain;  ///< A vector which contains all amino acids in the protein.

}; // Protein class

int main() {
  Protein chain;
  chain.parseInput("HPHHHPPPPHHHPHP");
  AminoAcid o = chain.get(1);
  std::cout << o.toString() << std::endl;
  o = chain.get(2);
  std::cout << o.toString() << std::endl;
  return 0;
}